/**
 * Copyright (C) 2012  The CFuture Android SDK Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lurencun.android.toolkit.network;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import android.util.Log;

/**
 * 提供下载功能的任务管理类
 * @author cfuture.chenyoca [桥下一粒砂] (chenyoca@163.com)
 * @date 2012-2-15
 */
public class DownloadTask {

	private final static String TAG = "DownloadTask";


	private List<DownThread> mThreads = new ArrayList<DownThread>();
	private DownloadTaskListener mListener;
	
	private int mId;
	
	private class DownTask {
		public int id;
		public String url;
		public String savePath;
	}


	/**
	 * 设置下载任务回调接口。
	 * @param listener
	 */
	public void setTaskListener(DownloadTaskListener listener) {
		mListener = listener;
	}

	/**
	 * 添加下载任务。
	 * 执行此方法则创建一个下载线程。
	 * @param url 下载URL
	 * @param savePath 保存地址。请保证保存路径正确可读。
	 * @return 任务ID
	 */
	public int addTask(String url, String savePath) {
		DownTask task = new DownTask();
		task.id = mId;
		task.savePath = savePath;
		task.url = url;
		DownThread thread = new DownThread(task);
		new Thread(thread).start();
		mThreads.add(thread);
		return mId++;
	}
	
	public void cancleTask(int id){
		mThreads.get(id).cancleThread();
	}

	/**
	 * 下载线程
	 * 
	 * @author cfuture.chenyoca [桥下一粒砂] (chenyoca@163.com)
	 * @date 2012-2-15
	 */
	private class DownThread implements Runnable {
		private final static int BLOCK_SIZE = 1024;
		private DownTask mTask;
		private Boolean mIsCancle = false;
		
		public DownThread(DownTask task) {
			mTask = task;
		}
		
		/**
		 * 取消下载线程
		 */
		public void cancleThread(){
			synchronized(mIsCancle){
				mIsCancle = false;
			}
		}
		@Override
		public void run() {
			try {
				URL url = new URL(mTask.url);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				if (HttpURLConnection.HTTP_OK == conn.getResponseCode()) {
					RandomAccessFile accessFile = new RandomAccessFile(mTask.savePath, "rwd");
					byte[] buffer = new byte[BLOCK_SIZE];
					int bufferSize = 0;
					int resourceSize = conn.getContentLength() - 1;
					accessFile.setLength(resourceSize);
					long downloadedSize = 0L;
					BufferedInputStream cache = new BufferedInputStream(conn.getInputStream());
					while ((bufferSize = cache.read(buffer)) != -1) {
						accessFile.write(buffer, 0, bufferSize);
						downloadedSize += bufferSize;
						int progress = Math.round((float) downloadedSize / resourceSize * 100);
						mListener.onProcess(mTask.id, progress);
					}
					cache.close();
					accessFile.close();
					if(mIsCancle){
						mListener.onCancle(mTask.id);
					}else{
						mListener.onCompleted(mTask.id);
					}
				} else {
					mListener.onFailed(mTask.id, "服务器响应错误！");
				}
				conn.disconnect();
			} catch (MalformedURLException e) {
				Log.e(TAG, " ==> 解析URL发生错误：" + e.getMessage());
				mListener.onFailed(mTask.id, "URL错误！");
			} catch (IOException e) {
				Log.e(TAG, " ==> 下载时发生IO错误：" + e.getMessage());
				mListener.onFailed(mTask.id, "下载时发生IO错误！");
			}
		}

	}

}
